package main

import (
	"fmt"
	"sync"
)

// 一个自制的简易并发安全字典
type ConcurrentMap struct {
	m map[interface{}]interface{}
	mu sync.RWMutex
}

func NewConcurrentMap() *ConcurrentMap {
	return &ConcurrentMap{
		m: make(map[interface{}]interface{}),
	}
}

func (cm *ConcurrentMap) Delete(key interface{}) {
	cm.mu.Lock()
	defer cm.mu.Unlock()
	delete(cm.m, key)
}

func (cm *ConcurrentMap) Load(key interface{}) (value interface{}, ok bool) {
	cm.mu.RLock()
	defer cm.mu.RUnlock()
	value, ok = cm.m[key]
	return
}

func (cm *ConcurrentMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
	cm.mu.Lock()
	defer cm.mu.Unlock()
	actual, loaded = cm.m[key]
	if loaded {
		return
	}
	cm.m[key] = value
	actual = value
	return
}

func (cm *ConcurrentMap) Store(key, value interface{}) {
	cm.mu.Lock()
	defer cm.mu.Unlock()
	cm.m[key] = value
}

func (cm *ConcurrentMap) Range(f func(key, value interface{}) bool) {
	cm.mu.RLock()
	defer cm.mu.RUnlock()
	for k, v := range cm.m {
		if !f(k, v) {
			break
		}
	}
}

func main() {
	pairs := []struct{
		k string
		v int
	}{
		{"k1", 1},
		{"k2", 2},
		{"k3", 3},
		{"k4", 4},
	}

	{
		fmt.Println("创建map")
		cm := NewConcurrentMap()
		for i := range pairs {
			cm.Store(pairs[i].k, pairs[i].v)
		}
		fmt.Println(cm.m)

		fmt.Println("遍历输出map")
		cm.Range (func(k, v interface{}) bool {
			fmt.Printf("%v: %v\n", k, v)
			return true
		})

		fmt.Println("Load 和 LoadOrStore 方法")
		key := "k3"
		value, ok := cm.Load(key)
		fmt.Printf("Load %v: %v: %v\n", ok, key, value)
		value, ok = cm.LoadOrStore(key, 5)
		fmt.Printf("LoadOrStore %v: %v: %v\n", ok, key, value)
		key = "k5"
		value, ok = cm.Load(key)
		fmt.Printf("Load %v: %v: %v\n", ok, key, value)
		value, ok = cm.LoadOrStore(key, 5)
		fmt.Printf("LoadOrStore %v: %v: %v\n", ok, key, value)
		fmt.Println(cm.m)

		fmt.Println("Delete 方法")
		key = "k2"
		cm.Delete(key)
		fmt.Println(cm.m)
		key = "k21"
		cm.Delete(key)
		fmt.Println(cm.m)
	}
	fmt.Println("Over")
}